//
// Created by Wei on 2022/5/16.
//
#include "compact_header.h"

void COMPACT_HEADER::set_delete_mask(bool flag) {
    if (flag)
        this->head_info[0] |= 0b00100000;
    else
        this->head_info[0] &= 0b11011111;
}


bool COMPACT_HEADER::isDeleted() {
    return this->head_info[0] & 0x0b00100000;
}

void COMPACT_HEADER::set_min_rec_mask(bool flag) {
    if (flag)
        this->head_info[0] |= 0b00010000;
    else
        this->head_info[0] &= 0b11101111;
}

bool COMPACT_HEADER::isMinRec() {
    return this->head_info[1] & 0b00010000;
}

void COMPACT_HEADER::set_n_owned(unsigned char n_owned) {
    this->head_info[0] &= 0b11110000;
    this->head_info[0] |= (n_owned & 0b00001111);
}

unsigned char COMPACT_HEADER::get_n_owned() {
    return this->head_info[0] & 0b00001111;
}

void COMPACT_HEADER::set_heap_no(unsigned short heap_no) {
    this->head_info[1] &= 0;
    this->head_info[2] &= 0b00000111;
    this->head_info[1] |= (heap_no >> 5);//0001 1111 1111 1111 -> 0000 0000 [1111 1111]
    this->head_info[2] |= (heap_no & 0b00011111) << 3;//0001 1111 1111 1111->0001 1111->1111 1000
}

unsigned short COMPACT_HEADER::get_heap_no() {
    unsigned short ret = 0;
    ret |= (this->head_info[1] << 5);//[1111 1111] -> 0001 1111 1110 0000
    ret |= (this->head_info[2] >> 3);//[1111 1000] -> 0000 0000 0001 1111
    return ret;
}

void COMPACT_HEADER::set_record_type(unsigned char record_type) {
    this->head_info[2] &= 0b11111000;
    this->head_info[2] |= (0b00000111 & record_type);
}

unsigned char COMPACT_HEADER::get_record_type() {
    return this->head_info[2] & 0b00000111;
}

void COMPACT_HEADER::set_next_record(unsigned short next_record) {
    this->head_info[3] = next_record >> 8;
    this->head_info[4] = next_record & 0xff;
}

unsigned short COMPACT_HEADER::get_next_record() {
    unsigned short n = 0;
    n |= head_info[3] << 8;
    n |= head_info[4];
    return n;
}

void COMPACT_HEADER::set(bool delete_mask, bool min_rec_mask, unsigned char n_owned, unsigned short heap_no,
                         unsigned char record_type, unsigned short next_record) {
    this->set_delete_mask(delete_mask);
    this->set_min_rec_mask(min_rec_mask);
    this->set_n_owned(n_owned);
    this->set_heap_no(heap_no);
    this->set_record_type(record_type);
    this->set_next_record(next_record);
}


